package com.datatrans.ui;

import com.datatrans.config.TransferConfig;
import com.datatrans.service.DatabaseService;
import com.datatrans.service.DataTransferService;
import com.datatrans.exception.TransferException;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.*;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库表数据迁移工具图形用户界面
 */
public class DataTransferGUI extends JFrame {
    // 源数据库面板组件
    private JTextField sourceUrlField;
    private JTextField sourceUsernameField;
    private JPasswordField sourcePasswordField;
    private JComboBox<TransferConfig.DatabaseType> sourceDbTypeCombo;
    
    // 目标数据库面板组件
    private JTextField targetUrlField;
    private JTextField targetUsernameField;
    private JPasswordField targetPasswordField;
    private JComboBox<TransferConfig.DatabaseType> targetDbTypeCombo;
    
    // 表配置面板组件
    private JTable tableMappingTable;
    private DefaultTableModel tableMappingModel;
    private JButton addButton;
    private JButton removeButton;
    private JComboBox<TransferConfig.TransferMode> modeCombo;
    
    // 控制按钮
    private JButton transferButton;
    private JButton testSourceConnectionButton;
    private JButton testTargetConnectionButton;
    private JButton clearButton;
    private JButton saveConfigButton;
    private JButton loadConfigButton;
    private JButton applyConfigButton;
    private JTextArea logArea;
    private JScrollPane logScrollPane;
    
    // 当前生效的配置
    private TransferConfig currentConfig;
    
    public DataTransferGUI() {
        initializeComponents();
        setupLayout();
        setupEventHandlers();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("数据库表数据迁移工具");
        setSize(900, 700);
        setLocationRelativeTo(null); // 居中显示
        
        // 初始化当前配置
        try {
            currentConfig = createConfig();
        } catch (Exception e) {
            // 忽略初始化错误
        }
    }
    
    private void initializeComponents() {
        // 初始化源数据库组件
        sourceUrlField = new JTextField(20);
        sourceUrlField.setText("jdbc:mysql://localhost:3306/source_db");
        sourceUsernameField = new JTextField(20);
        sourceUsernameField.setText("root");
        sourcePasswordField = new JPasswordField(20);
        sourceDbTypeCombo = new JComboBox<>(TransferConfig.DatabaseType.values());
        
        // 初始化目标数据库组件
        targetUrlField = new JTextField(20);
        targetUrlField.setText("jdbc:postgresql://localhost:5432/target_db");
        targetUsernameField = new JTextField(20);
        targetUsernameField.setText("postgres");
        targetPasswordField = new JPasswordField(20);
        targetDbTypeCombo = new JComboBox<>(TransferConfig.DatabaseType.values());
        
        // 初始化表配置组件
        String[] columnNames = {"源表名", "目标表名"};
        tableMappingModel = new DefaultTableModel(columnNames, 0);
        tableMappingTable = new JTable(tableMappingModel) {
            // 重写isCellEditable方法确保所有单元格可编辑
            @Override
            public boolean isCellEditable(int row, int column) {
                return true;
            }
        };
        tableMappingTable.setPreferredScrollableViewportSize(new Dimension(300, 100));
        // 启用表格编辑并设置相关属性
        tableMappingTable.setCellSelectionEnabled(true);
        tableMappingTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        tableMappingTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
        tableMappingTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
        // 设置默认编辑器以提高输入体验
        tableMappingTable.setDefaultEditor(Object.class, new DefaultCellEditor(new JTextField()));
        // 启用双击编辑
        tableMappingTable.setSurrendersFocusOnKeystroke(true);
        
        addButton = new JButton("添加");
        removeButton = new JButton("删除");
        modeCombo = new JComboBox<>(TransferConfig.TransferMode.values());
        modeCombo.setSelectedItem(TransferConfig.TransferMode.UPDATE); // 默认改为更新模式
        
        // 初始化控制按钮
        transferButton = new JButton("开始迁移");
        testSourceConnectionButton = new JButton("测试源数据库连接");
        testTargetConnectionButton = new JButton("测试目标数据库连接");
        clearButton = new JButton("清空日志");
        saveConfigButton = new JButton("保存配置");
        loadConfigButton = new JButton("加载配置");
        applyConfigButton = new JButton("应用配置");
        
        // 初始化日志区域
        logArea = new JTextArea(10, 50);
        logArea.setEditable(false);
        logScrollPane = new JScrollPane(logArea);
        
        // 添加使用说明到日志区域
        logArea.setText("数据库表数据迁移工具使用说明:\n" +
                       "1. 填写源数据库连接信息\n" +
                       "2. 填写目标数据库连接信息\n" +
                       "3. 添加需要迁移的表映射（源表名和目标表名）\n" +
                       "4. 点击\"测试源数据库连接\"和\"测试目标数据库连接\"按钮测试连接\n" +
                       "5. 选择迁移模式\n" +
                       "6. 点击\"应用配置\"使配置生效\n" +
                       "7. 点击\"开始迁移\"按钮执行迁移\n\n" +
                       "注意: 确保数据库服务正在运行且可以访问\n");
    }
    
    private void setupLayout() {
        setLayout(new BorderLayout());
        
        // 创建主面板
        JPanel mainPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = GridBagConstraints.WEST;
        
        // 源数据库配置面板
        JPanel sourcePanel = new JPanel(new GridBagLayout());
        sourcePanel.setBorder(BorderFactory.createTitledBorder("源数据库配置"));
        gbc.gridx = 0; gbc.gridy = 0;
        sourcePanel.add(new JLabel("数据库URL:"), gbc);
        gbc.gridx = 1;
        sourcePanel.add(sourceUrlField, gbc);
        gbc.gridx = 0; gbc.gridy = 1;
        sourcePanel.add(new JLabel("用户名:"), gbc);
        gbc.gridx = 1;
        sourcePanel.add(sourceUsernameField, gbc);
        gbc.gridx = 0; gbc.gridy = 2;
        sourcePanel.add(new JLabel("密码:"), gbc);
        gbc.gridx = 1;
        sourcePanel.add(sourcePasswordField, gbc);
        gbc.gridx = 0; gbc.gridy = 3;
        sourcePanel.add(new JLabel("数据库类型:"), gbc);
        gbc.gridx = 1;
        sourcePanel.add(sourceDbTypeCombo, gbc);
        gbc.gridx = 0; gbc.gridy = 4;
        sourcePanel.add(testSourceConnectionButton, gbc);
        
        // 目标数据库配置面板
        JPanel targetPanel = new JPanel(new GridBagLayout());
        targetPanel.setBorder(BorderFactory.createTitledBorder("目标数据库配置"));
        gbc.gridx = 0; gbc.gridy = 0;
        targetPanel.add(new JLabel("数据库URL:"), gbc);
        gbc.gridx = 1;
        targetPanel.add(targetUrlField, gbc);
        gbc.gridx = 0; gbc.gridy = 1;
        targetPanel.add(new JLabel("用户名:"), gbc);
        gbc.gridx = 1;
        targetPanel.add(targetUsernameField, gbc);
        gbc.gridx = 0; gbc.gridy = 2;
        targetPanel.add(new JLabel("密码:"), gbc);
        gbc.gridx = 1;
        targetPanel.add(targetPasswordField, gbc);
        gbc.gridx = 0; gbc.gridy = 3;
        targetPanel.add(new JLabel("数据库类型:"), gbc);
        gbc.gridx = 1;
        targetPanel.add(targetDbTypeCombo, gbc);
        gbc.gridx = 0; gbc.gridy = 4;
        targetPanel.add(testTargetConnectionButton, gbc);
        
        // 表配置面板
        JPanel tablePanel = new JPanel(new GridBagLayout());
        tablePanel.setBorder(BorderFactory.createTitledBorder("表配置"));
        
        // 表映射表格
        gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth = 2;
        tablePanel.add(new JScrollPane(tableMappingTable), gbc);
        
        // 按钮面板
        JPanel buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.add(addButton);
        buttonPanel.add(removeButton);
        
        gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2;
        tablePanel.add(buttonPanel, gbc);
        
        // 迁移模式
        gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 1;
        tablePanel.add(new JLabel("迁移模式:"), gbc);
        gbc.gridx = 1;
        tablePanel.add(modeCombo, gbc);
        
        // 控制按钮面板
        JPanel controlPanel = new JPanel(new FlowLayout());
        controlPanel.add(transferButton);
        controlPanel.add(applyConfigButton);
        controlPanel.add(saveConfigButton);
        controlPanel.add(loadConfigButton);
        controlPanel.add(clearButton);
        
        // 将各面板添加到主面板
        gbc.gridx = 0; gbc.gridy = 0;
        mainPanel.add(sourcePanel, gbc);
        gbc.gridx = 1;
        mainPanel.add(targetPanel, gbc);
        gbc.gridx = 0; gbc.gridy = 1; gbc.gridwidth = 2;
        mainPanel.add(tablePanel, gbc);
        gbc.gridy = 2;
        mainPanel.add(controlPanel, gbc);
        
        // 添加到主窗口
        add(mainPanel, BorderLayout.NORTH);
        add(logScrollPane, BorderLayout.CENTER);
    }
    
    private void setupEventHandlers() {
        transferButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                startTransfer();
            }
        });
        
        testSourceConnectionButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                testSourceConnection();
            }
        });
        
        testTargetConnectionButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                testTargetConnection();
            }
        });
        
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                addTableRow();
            }
        });
        
        removeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                removeTableRow();
            }
        });
        
        clearButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                logArea.setText("");
            }
        });
        
        saveConfigButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                saveConfig();
            }
        });
        
        loadConfigButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                loadConfig();
            }
        });
        
        applyConfigButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                applyConfiguration();
            }
        });
        
        // 为整个窗口添加焦点监听器，使表名输入框在失去焦点时能更新数据
        this.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                // 当窗口失去焦点时，确保表格数据被提交
                if (tableMappingTable.isEditing()) {
                    tableMappingTable.getCellEditor().stopCellEditing();
                }
            }
        });
        
        // 为表格添加焦点监听器
        tableMappingTable.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                // 当表格失去焦点时，确保正在编辑的单元格提交数据
                if (tableMappingTable.isEditing()) {
                    tableMappingTable.getCellEditor().stopCellEditing();
                }
            }
        });
        
        // 添加鼠标双击事件监听器，实现双击进入编辑状态
        tableMappingTable.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                if (evt.getClickCount() == 2) { // 双击事件
                    int row = tableMappingTable.rowAtPoint(evt.getPoint());
                    int col = tableMappingTable.columnAtPoint(evt.getPoint());
                    if (row >= 0 && col >= 0) {
                        // 请求焦点以确保表格可以编辑
                        tableMappingTable.requestFocusInWindow();
                        // 使用SwingUtilities.invokeLater确保在事件处理完成后执行编辑
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                tableMappingTable.editCellAt(row, col);
                                Component editorComponent = tableMappingTable.getEditorComponent();
                                if (editorComponent != null) {
                                    editorComponent.requestFocusInWindow();
                                    // 添加视觉反馈，让用户知道已进入编辑状态
                                    if (editorComponent instanceof JComponent) {
                                        ((JComponent) editorComponent).setBorder(BorderFactory.createLineBorder(Color.BLUE, 2));
                                    }
                                }
                            }
                        });
                    }
                }
            }
        });
    }
    
    private void addTableRow() {
        tableMappingModel.addRow(new Object[]{"users", "user_table"});
    }
    
    private void removeTableRow() {
        int selectedRow = tableMappingTable.getSelectedRow();
        if (selectedRow >= 0) {
            tableMappingModel.removeRow(selectedRow);
        } else {
            JOptionPane.showMessageDialog(this, "请先选择要删除的行", "提示", JOptionPane.WARNING_MESSAGE);
        }
    }
    
    private void saveConfig() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("保存配置文件");
        fileChooser.setSelectedFile(new File("transfer_config.dat"));
        int userSelection = fileChooser.showSaveDialog(this);
        
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            File fileToSave = fileChooser.getSelectedFile();
            try {
                TransferConfig config = createConfig();
                ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileToSave));
                out.writeObject(config);
                out.close();
                logArea.append("配置已保存到: " + fileToSave.getAbsolutePath() + "\n");
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "保存配置失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }
    
    private void loadConfig() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("加载配置文件");
        int userSelection = fileChooser.showOpenDialog(this);
        
        if (userSelection == JFileChooser.APPROVE_OPTION) {
            File fileToLoad = fileChooser.getSelectedFile();
            try {
                ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileToLoad));
                TransferConfig config = (TransferConfig) in.readObject();
                in.close();
                
                // 应用配置到界面
                applyConfig(config);
                // 同步更新内存中的当前配置
                currentConfig = config;
                logArea.append("配置已从: " + fileToLoad.getAbsolutePath() + " 加载\n");
            } catch (Exception e) {
                JOptionPane.showMessageDialog(this, "加载配置失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                e.printStackTrace();
            }
        }
    }
    
    /**
     * 应用配置到界面（保持不变）
     * @param config 需要应用的配置对象
     */
    private void applyConfig(TransferConfig config) {
        // 应用源数据库配置
        sourceUrlField.setText(config.getSourceUrl());
        sourceUsernameField.setText(config.getSourceUsername());
        sourcePasswordField.setText(config.getSourcePassword());
        sourceDbTypeCombo.setSelectedItem(config.getSourceDbType());
        
        // 应用目标数据库配置
        targetUrlField.setText(config.getTargetUrl());
        targetUsernameField.setText(config.getTargetUsername());
        targetPasswordField.setText(config.getTargetPassword());
        targetDbTypeCombo.setSelectedItem(config.getTargetDbType());
        
        // 应用表映射配置
        tableMappingModel.setRowCount(0); // 清空现有行
        for (TransferConfig.TableMapping mapping : config.getTableMappings()) {
            tableMappingModel.addRow(new Object[]{mapping.getSourceTable(), mapping.getTargetTable()});
        }
        
        // 应用迁移模式
        modeCombo.setSelectedItem(config.getTransferMode());
    }
    
    /**
     * 获取当前生效的配置副本
     * @return 当前生效的配置
     */
    public TransferConfig getCurrentConfig() {
        return currentConfig;
    }
    
    private void testSourceConnection() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        testSourceConnectionButton.setEnabled(false);
                        logArea.append("正在测试源数据库连接...\n");
                    }
                });
                
                try {
                    TransferConfig config = createSourceConfig();
                    DatabaseService service = new DatabaseService();
                    Connection conn = service.getSourceConnection(config);
                    if (conn != null && !conn.isClosed()) {
                        conn.close();
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                logArea.append("源数据库连接测试成功！\n");
                            }
                        });
                    } else {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                logArea.append("源数据库连接测试失败：无法建立连接\n");
                            }
                        });
                    }
                } catch (Exception e) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            logArea.append("源数据库连接测试失败: " + e.getMessage() + "\n");
                            logArea.append("请检查源数据库连接信息是否正确，以及数据库服务是否正在运行。\n");
                        }
                    });
                } finally {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            testSourceConnectionButton.setEnabled(true);
                        }
                    });
                }
            }
        }).start();
    }
    
    private void testTargetConnection() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        testTargetConnectionButton.setEnabled(false);
                        logArea.append("正在测试目标数据库连接...\n");
                    }
                });
                
                try {
                    TransferConfig config = createTargetConfig();
                    DatabaseService service = new DatabaseService();
                    Connection conn = service.getTargetConnection(config);
                    if (conn != null && !conn.isClosed()) {
                        conn.close();
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                logArea.append("目标数据库连接测试成功！\n");
                            }
                        });
                    } else {
                        SwingUtilities.invokeLater(new Runnable() {
                            @Override
                            public void run() {
                                logArea.append("目标数据库连接测试失败：无法建立连接\n");
                            }
                        });
                    }
                } catch (Exception e) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            logArea.append("目标数据库连接测试失败: " + e.getMessage() + "\n");
                            logArea.append("请检查目标数据库连接信息是否正确，以及数据库服务是否正在运行。\n");
                        }
                    });
                } finally {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            testTargetConnectionButton.setEnabled(true);
                        }
                    });
                }
            }
        }).start();
    }
    
    private void startTransfer() {
        // 在新线程中执行迁移操作，避免阻塞UI
        new Thread(new Runnable() {
            @Override
            public void run() {
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        transferButton.setEnabled(false);
                        logArea.append("开始数据迁移...\n");
                    }
                });
                
                try {
                    // 使用已应用的配置执行迁移
                    DataTransferService service = new DataTransferService();
                    service.transfer(currentConfig);
                    
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            logArea.append("数据迁移完成！\n");
                        }
                    });
                } catch (Exception e) {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            logArea.append("数据迁移失败: " + e.getMessage() + "\n");
                            logArea.append("请检查数据库连接信息是否正确，以及数据库服务是否正在运行。\n");
                            e.printStackTrace();
                        }
                    });
                } finally {
                    SwingUtilities.invokeLater(new Runnable() {
                        @Override
                        public void run() {
                            transferButton.setEnabled(true);
                        }
                    });
                }
            }
        }).start();
    }
    
    /**
     * 应用当前界面配置到内存中
     */
    private void applyConfiguration() {
        try {
            currentConfig = createConfig();
            logArea.append("配置已应用\n");
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "配置应用失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }
    
    private TransferConfig createSourceConfig() throws TransferException {
        TransferConfig config = new TransferConfig();
        
        // 源数据库配置
        String sourceUrl = sourceUrlField.getText().trim();
        if (sourceUrl.isEmpty()) {
            throw new TransferException("源数据库URL不能为空");
        }
        config.setSourceUrl(sourceUrl);
        
        String sourceUsername = sourceUsernameField.getText().trim();
        if (sourceUsername.isEmpty()) {
            throw new TransferException("源数据库用户名不能为空");
        }
        config.setSourceUsername(sourceUsername);
        
        config.setSourcePassword(new String(sourcePasswordField.getPassword()));
        config.setSourceDbType((TransferConfig.DatabaseType) sourceDbTypeCombo.getSelectedItem());
        
        return config;
    }
    
    private TransferConfig createTargetConfig() throws TransferException {
        TransferConfig config = new TransferConfig();
        
        // 目标数据库配置
        String targetUrl = targetUrlField.getText().trim();
        if (targetUrl.isEmpty()) {
            throw new TransferException("目标数据库URL不能为空");
        }
        config.setTargetUrl(targetUrl);
        
        String targetUsername = targetUsernameField.getText().trim();
        if (targetUsername.isEmpty()) {
            throw new TransferException("目标数据库用户名不能为空");
        }
        config.setTargetUsername(targetUsername);
        
        config.setTargetPassword(new String(targetPasswordField.getPassword()));
        config.setTargetDbType((TransferConfig.DatabaseType) targetDbTypeCombo.getSelectedItem());
        
        return config;
    }
    
    private TransferConfig createConfig() throws TransferException {
        TransferConfig config = new TransferConfig();
        
        // 源数据库配置
        String sourceUrl = sourceUrlField.getText().trim();
        if (sourceUrl.isEmpty()) {
            throw new TransferException("源数据库URL不能为空");
        }
        config.setSourceUrl(sourceUrl);
        
        String sourceUsername = sourceUsernameField.getText().trim();
        if (sourceUsername.isEmpty()) {
            throw new TransferException("源数据库用户名不能为空");
        }
        config.setSourceUsername(sourceUsername);
        
        config.setSourcePassword(new String(sourcePasswordField.getPassword()));
        config.setSourceDbType((TransferConfig.DatabaseType) sourceDbTypeCombo.getSelectedItem());
        
        // 目标数据库配置
        String targetUrl = targetUrlField.getText().trim();
        if (targetUrl.isEmpty()) {
            throw new TransferException("目标数据库URL不能为空");
        }
        config.setTargetUrl(targetUrl);
        
        String targetUsername = targetUsernameField.getText().trim();
        if (targetUsername.isEmpty()) {
            throw new TransferException("目标数据库用户名不能为空");
        }
        config.setTargetUsername(targetUsername);
        
        config.setTargetPassword(new String(targetPasswordField.getPassword()));
        config.setTargetDbType((TransferConfig.DatabaseType) targetDbTypeCombo.getSelectedItem());
        
        // 表配置
        List<TransferConfig.TableMapping> mappings = new ArrayList<>();
        for (int i = 0; i < tableMappingModel.getRowCount(); i++) {
            String sourceTable = (String) tableMappingModel.getValueAt(i, 0);
            String targetTable = (String) tableMappingModel.getValueAt(i, 1);
            
            if (sourceTable != null && !sourceTable.trim().isEmpty()) {
                TransferConfig.TableMapping mapping = new TransferConfig.TableMapping();
                mapping.setSourceTable(sourceTable.trim());
                mapping.setTargetTable(targetTable != null && !targetTable.trim().isEmpty() ? 
                                      targetTable.trim() : sourceTable.trim());
                mappings.add(mapping);
            }
        }
        
        if (mappings.isEmpty()) {
            throw new TransferException("至少需要配置一个表映射");
        }
        
        config.setTableMappings(mappings);
        config.setTransferMode((TransferConfig.TransferMode) modeCombo.getSelectedItem());
        
        return config;
    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    // 使用默认外观
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                
                new DataTransferGUI().setVisible(true);
            }
        });
    }
}